import { createRequire } from 'module'
import path from 'path'
import { fileURLToPath, pathToFileURL } from 'url'

export const once = <F extends (...args: any[]) => any>(fn: F): F => {
  let result: any
  let isCalled = false

  return ((...args: any[]) => {
    if (isCalled) {
      return result
    } else {
      result = fn(...args)
      isCalled = true
      return result
    }
  }) as any
}


export const createDynamicImport = (_fileName: string): ((id: string) => Promise<any>) => {
  if (_fileName.endsWith('.mjs')) {
    return id => {
      if (path.isAbsolute(id)) {
        id = pathToFileURL(id).href
      }

      return import(id)
    }
  } else {
    const _require = createRequire(_fileName)
    return async id => _require(id)
  }
}

export const _fileName = typeof __filename === 'string' ? __filename : fileURLToPath(import.meta.url)
export const _is_esm = _fileName.endsWith('.mjs')
export const _import = createDynamicImport(_fileName)
